//
//  LTStethoscopeSDK.m
//  hc21SDK
//
//  Created by lanzhongping on 2021/1/6.
//

#import "LTSRingSDK.h"
#import "SRBleDiscovery.h"
#import "SRBLeService.h"
#import "SROtaManager.h"
#import "SRPacket.h"
#import "SRDeviceInfo.h"
#import "DBTables.h"
#import "SRHistoryDataSR03+OtherCalc.h"
#import "TimeUtils.h"
#import "SleepStagingV2.h"
#import "SdkInnerHeader.h"
#import "SDKTool.h"
#import "SleepSourceData.h"
#import "NSKAlgoSDKECG.h"
//#import "SleepStagingV2+sleepCLibCall.h"


NSString * const DEF_COMPANY = @"Linktop";

@interface LTSRingSDK()<STLeDiscoveryDelegate, StLeKeyFobProtocol, NSKAlgoSDKECGDelegate>

@property(strong, nonatomic)SROtaManager *otaManager;

@property(strong, nonatomic)NSString *currentMac;
@property(assign, nonatomic)NSInteger historyCacheCount, currHisidx; //此次历史数据条目
@property(assign, nonatomic)NSInteger fakeHisIncrease; //同步进度条假增加

@property(strong, nonatomic)NSMutableArray<SRHistoryDataSR03 *> *historyCacheArray; //缓存历史数据
@property(strong, nonatomic)SleepStagingV2 *sleepStageCalcObj; //睡眠计算

@property(strong, nonatomic)SRBLeService *currentPerphelServc;

@property(strong, nonatomic)NSMutableArray *cacheDbSleepArray;  // 睡眠计算时缓存持有

@property(strong, nonatomic)NSString *aesCompany; // 认证厂家码
@property(strong, nonatomic)EcgParamObj *ecgParamObj;
@property(strong, nonatomic)NSNumber *isRowWave; // 标记ecg的开启方式是否滤波

@property(strong, nonatomic)NSNumber *hrLimitLow; //心率过滤下限

@property(strong, nonatomic)NSKAlgoSDKECG *algoEcgSdkObj;


@end

@implementation LTSRingSDK
{
    
}

+(instancetype)instance
{
    static LTSRingSDK *this = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        this = [[LTSRingSDK alloc] init];
    });
    return this;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.hrLimitLow = @(HR_LOW);
    }
    return self;
}

-(void)registWithCompany:(NSString  * _Nullable )cp {
    [self createDbTables];
    self.sleepStageCalcObj = [[SleepStagingV2 alloc]init];

    
    [[SRBleDiscovery sharedInstance]regist];
    [[SRBleDiscovery sharedInstance] setDiscoveryDelegate:self];
    [[SRBleDiscovery sharedInstance]  setPeripheralDelegate:self];
    
    self.aesCompany = cp;
    if (!self.aesCompany.length) {
        self.aesCompany = DEF_COMPANY;
    }
    
}

/// Set the SDK's lower filter limit for heart rate data.If this interface is not called, the default lower limit is 45.
/// - Parameter hrLimitLow: 下限值范围[0-200]
-(void)setHeartrateFilterLowerLimit:(NSUInteger)hrLimitLow
{
    self.hrLimitLow = @(hrLimitLow);
}

// Get the SDK's lower filter limit for heart rate data.
-(NSUInteger)heartrateFilterLowerLimit
{
    return self.hrLimitLow.unsignedIntegerValue;
}


-(void)setBleOtaDelegate:(id<SROTAProtocal>)bleOtaDelegate
{
    _bleOtaDelegate = bleOtaDelegate;
    self.otaManager.bleOtaDelegate = _bleOtaDelegate;
}



-(void)setCurrentPeripheralService:(SRBLeService* _Nullable)peripheralService;
{
    
    [self.currentPerphelServc setPerpheralDelegate:nil];
    
    self.currentPerphelServc = peripheralService;
    
    DebugNSLog(@"传入service %@ %@", self.currentPerphelServc.perpheralDelegate, [SRBleDiscovery sharedInstance].peripheralDelegate);
    
    if (self.currentPerphelServc &&
        self.currentPerphelServc.perpheralDelegate != [SRBleDiscovery sharedInstance].peripheralDelegate)
    {
        // 代理不同 说明从外部扫描传入
        [self.currentPerphelServc setPerpheralDelegate:[SRBleDiscovery sharedInstance].peripheralDelegate];
        [self.currentPerphelServc start];
    }
    
    [[SRBleDiscovery sharedInstance] ousideSetCurrentService:self.currentPerphelServc];// 从外部扫描传入
    
//    self.accountName = account;
    self.cacheDbSleepArray = nil;
}

-(void)cleanAccount
{
    self.currentMac = nil;
}

//- (CBManagerState)deviceBleCenterState {
//    
//    return [[SRBleDiscovery sharedInstance] deviceBleCenterState];
//}

-(void)startBleScan
{
    
    [[SRBleDiscovery sharedInstance] startScanning:LEDISCOVERY_SCANTYPE_LISTCHOOSE];
}

-(void)stopBleScan
{
    [[SRBleDiscovery sharedInstance] stopScanning];
}

-(void)connectDevice:(SRBLeService *)device {
    if (device) {
        [[SRBleDiscovery sharedInstance] connectPeripheral:device];
    }
}
-(void)disconnectCurrentService {
    [[SRBleDiscovery sharedInstance] disconnectPeripheral:[[SRBleDiscovery sharedInstance] currentService]];
    // 直接回调disconnect
    [[SRBleDiscovery sharedInstance] currentService].hasBeenAuth = NO;
    if ([self.blescanDelegate respondsToSelector:@selector(srBleDidDisconnectPeripheral:)]) {
        [self.blescanDelegate srBleDidDisconnectPeripheral:[[SRBleDiscovery sharedInstance] currentService]];
    }
    
}



- (CBManagerState)bleCenterManagerState {
    return [[SRBleDiscovery sharedInstance] deviceBleCenterState];

}

/// 获取心率血氧开关
/// @param isStart isStart = NO 关闭  isStart = yes 开启
-(void)functionOxygenOrHeartRate:(REALTIME_MEASURE_TYPE)type IsOpen:(BOOL)isStart
{
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    
    BOOL both = NO;
    if (type == REALTIME_MEASURE_SPO) {
        both = YES;
    }
    
    if (isStart) {
        // 先关闭
        [[[SRBleDiscovery sharedInstance] currentService] deviceOxygenAndHrvBoth:both IsOpen:NO];
    }
    
    // 延时开始
    [[[SRBleDiscovery sharedInstance] currentService] deviceOxygenAndHrvBoth:both IsOpen:isStart];

    
}

/// send cmd to power off device
-(void)functionShutDownDevice {
    FUNCTION_ERROR funcErr = [self functionProtect:NO];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdDeviceShutDown];
}


/// send cmd to reboot device
-(void)functionRebootDevice {
    FUNCTION_ERROR funcErr = [self functionProtect:NO];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdDeviceReboot];
}

-(SRBLeService *)currentDevice {
    return  [[SRBleDiscovery sharedInstance] currentService];
}

/// get device's battery
-(void)functionGetDeviceBattery {
//    DebugNSLog(@"[[SRBleDiscovery sharedInstance] currentService] = %@", [[SRBleDiscovery sharedInstance] currentService]);
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    
    [[[SRBleDiscovery sharedInstance] currentService] cmdDeviceBattery];
    
}

/// get steps
-(void)functionGetStepsOnce
{
    return;
//    [[[SRBleDiscovery sharedInstance] currentService] cmdGetSteps];
}

/// 直接获取数据 用于设备测量中的延迟获取
-(void)functionGetHistoryDataOnlyData {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    // 开始获取历史数据
    [[[SRBleDiscovery sharedInstance] currentService] cmdHistoryData];
}

/// get skin temperature
-(void)functionGetTemperatureOnce
{
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdGetTemperature];
}


/// device reset to factory status
-(void)functionDeviceReset
{
    FUNCTION_ERROR funcErr = [self functionProtect:NO];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdFactoryReset];
}

-(void)functionGetDeviceSN {
    FUNCTION_ERROR funcErr = [self functionProtect:NO];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    
    [[[SRBleDiscovery sharedInstance] currentService] cmdSn];

}

-(void)functionGetDeviceInfo {
    FUNCTION_ERROR funcErr = FUNCTION_ERR_NONE;
    // 未连接
    if ([[SRBleDiscovery sharedInstance] currentService].peripheral.state != CBPeripheralStateConnected) {
        funcErr = FUNCTION_ERR_BLE_NOT_CONNECT;
        
    }
    // 读写未准备好
    if (! [[[SRBleDiscovery sharedInstance] currentService] characteristicReadWriteReady]) {
        funcErr = FUNCTION_ERR_BLE_NOTREADY_READWRITE;
    }
    
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    // 设备信息
    [[[SRBleDiscovery sharedInstance] currentService] cmdDevInfo];

}

-(void)functionSetRealmeasureWaveSwitch:(BOOL)isON {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdDevRealMeasureWaveOn:isON];

}


// 设置血氧测量
-(BOOL)functionSettingOxygenMeasure:(NSUInteger)startHor StartMin:(NSUInteger)startMin StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec Interval:(NSUInteger)interval IsOn:(BOOL)isOn {
    
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return NO;
    }
    return [[[SRBleDiscovery sharedInstance] currentService] cmdSettingOxygenMeasure:startHor StartMin:startMin StartSec:startSecond Endhor:endHor EndMin:endMin EndSec:endSec Interval:interval IsOn:isOn];
}

-(void)functionSettingHeartRateMeasurInterval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval IsOn:(BOOL)isOn {
    [[[SRBleDiscovery sharedInstance] currentService] cmdSettingHeartRateMeasurInterval:hrInterval SkinTemperatureInterval:skinTemperatureInterval IsOn:isOn];
    return;
}

-(void)functionSettingSportMode:(NSUInteger)startHor StartMin:(NSUInteger)startMin
                       StartSec:(NSUInteger)startSecond Endhor:(NSUInteger)endHor
                         EndMin:(NSUInteger)endMin EndSec:(NSUInteger)endSec
                     HrIntreval:(NSUInteger)hrInterval SkinTemperatureInterval:(NSUInteger)skinTemperatureInterval
                       BloodOxygenInterval:(NSUInteger)oxygeninterval
                           IsOn:(BOOL)isOn
{
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdSettingSportMode:startHor StartMin:startMin
                                                              StartSec:startSecond Endhor:endHor
                                                                EndMin:endMin EndSec:endSec
                                                            HrIntreval:hrInterval SkinTemperatureInterval:skinTemperatureInterval
                                                              BloodOxygenInterval:oxygeninterval
                                                                  IsOn:isOn];
    return;
    
}

/// get device's cache history data
/// retrun YES = cmd send successful  retrun NO = the last history data process is translating
-(BOOL)functionGetHistoryData {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return NO;
    }
    // 检查上一次历史数据传输是否完成
    if ([[SRBleDiscovery sharedInstance] currentService].packetObj.isTranslatingHistory) {
        return NO;
    }
    
    // 下发获取历史个数指令
    [[[SRBleDiscovery sharedInstance] currentService] cmdHistoryCount];
    
    return  YES;
}

-(void)functionSetBindeDevice:(BOOL)bind {
    
    FUNCTION_ERROR funcErr = [self functionProtect:NO];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    // 下发获取历史个数指令
    [[[SRBleDiscovery sharedInstance] currentService] cmdBindeDevice:bind];
}

-(void)functionGetDeviceMeasureDuration {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    // 下发获取每次测量时长
    [[[SRBleDiscovery sharedInstance] currentService] cmdGetDevInfoFive];
}

-(void)functionSetDeviceMeasureDuration:(NSInteger)duration {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdSetMeasureDuration:duration];
}

/// 开启运动模式
/// @param durationMinutes 持续时间 单位:分钟 范围(5min - 180min)
-(void)functionStartSportMode:(uint16_t)durationMinutes ValueInterval:(uint16_t)valueInterval WorkType:(WORKOUT_TYPE)wkType
{
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdSportMode:YES ValueINterval:valueInterval Duration:durationMinutes WorkType:wkType];

}

/// 手动关闭运动模式
-(void)functionShutdownSportMode {
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdSportMode:NO ValueINterval:10 Duration:5 WorkType:WORKOUT_TYPE_OTHER];

}


-(void)functionSetSosDoubleTapTimes:(uint8_t)doubleTapTimes
    SingleTapInterval:(SOS_DOUBLESLAP_INTERVAL_TYPE)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
           DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Open:(BOOL)sosOpen
{
    [[[SRBleDiscovery sharedInstance] currentService] cmdSOSSettingDoubleTapTimes:doubleTapTimes
                                                                
                                                                SingleTapInterval:singleTapInterval
                                                            TapDetectionThreshold:tapDetectionThreshold
                                                                       
                                                         DoubleTapEffectStartTime:doubleTapEffectStartTime
                                                           DoubleTapEffectEndTime:doubleTapEffectEndTime
                                                                             Open:(BOOL)sosOpen];
    
    
}


/// 清空设备当前的所有历史缓存
-(void)functionClearDeviceHistoryCache
{
    FUNCTION_ERROR funcErr = [self functionProtect:YES];
    if (funcErr != FUNCTION_ERR_NONE) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleFunctionErrorCallBack:MehthodName:)]) {
            [self.bleDataDelegate srBleFunctionErrorCallBack:funcErr MehthodName:[NSString stringWithFormat:@"%s", __FUNCTION__]];
        }
        return;
    }
    [[[SRBleDiscovery sharedInstance] currentService] cmdClearHistory];
}

-(NSString *)macAddressFromBleAvdData:(NSDictionary *)advertisementData
{
    return  [SDKTool macAddressFromBleAvdData:advertisementData];
}

/// ecg测量
/// - Parameter on: YES 开 NO 关
/// - Parameter isRowWave:  NO = Output the data calculated by the algorithm, YES =Output raw data
-(BOOL)functionECGMeasure:(BOOL)on Param:(EcgParamObj * _Nullable)paramObj DispSrc:(BOOL)isRowWave
{
    
    if(on && !paramObj) {
        return NO;
    }
    
    if (on) {
        self.ecgParamObj = paramObj;
        if (!isRowWave) {
            self.ecgParamObj.disp_src = DISP_SRC_2;
        } else {
            self.ecgParamObj.disp_src = DISP_SRC_0;

        }
        self.isRowWave = @(isRowWave);
        [self.algoEcgSdkObj resetECGAnalysis]; //重置神念
    } else {
        self.isRowWave = nil;
    }
    
    uint16_t sampleRate = 0; // 采样率
    if (paramObj.clockSource == ECG_CLOCK_SRC_32768) {
        sampleRate = paramObj.sampleRateWhenSrc32768;
    }
    if (paramObj.clockSource == ECG_CLOCK_SRC_32000) {
        sampleRate = paramObj.sampleRateWhenSrc32000;
    }
    uint8_t clockSource = paramObj.clockSource; // 内部时钟
    uint8_t ecgPgaGain = paramObj.ecgPgaGainIdx; // 增益
    if (!paramObj) {
         sampleRate = 512; // 采样率
         clockSource = ECG_CLOCK_SRC_32768; // 内部时钟
         ecgPgaGain = ECG_PGA_GAIN_2; // 增益
    }
    
    
    [[[SRBleDiscovery sharedInstance] currentService] cmdECGMeasure:on SampleRate:sampleRate  InnerClockSource:clockSource EcgPgaGain:ecgPgaGain DispSrc:self.ecgParamObj.disp_src];

    return YES;
}

/// ecg和ppg同时测量
/// - Parameter on: YES 开 NO 关
-(void)functionEcgAndPpgMeasure:(BOOL)on
{
    [[[SRBleDiscovery sharedInstance] currentService] cmdEcgAndPpgMeasure:on];

}



-(NSString *)functionGetSdkVersion
{
    return @"1.2.2-1";
}



#pragma mark -- STLeDiscoveryDelegate

/// 扫描刷新 清除所有发现设备,连接过的设备, 断开已连接设备
- (void)stdiscoveryDidRefresh:(NSArray<SRBLeService *>*)perphelArray {
    
    if ([self.blescanDelegate respondsToSelector:@selector(srScanDeviceDidRefresh:)]) {
        [self.blescanDelegate srScanDeviceDidRefresh:perphelArray];
    }
    
}

// 手机蓝牙开启关闭回调
- (void)stdiscoveryStatePoweredState:(CBManagerState)state {
    if ([self.blescanDelegate respondsToSelector:@selector(srBlePowerStateChange:)]) {
        [self.blescanDelegate srBlePowerStateChange:state];
    }
}



- (void)stconnectPeripheralTimeout:(SRBLeService*)keyService {
    
}

- (void)stdidRetrievePeripherals:(NSArray *)peripherals {
    
}




#pragma mark -- StLeKeyFobProtocol


- (void) stkeyFobServiceDidChangeStatus:(SRBLeService*)service {
    
}
- (void) stkeyFobServiceDidConnectPeripheral:(SRBLeService*)service {
    
//    service.recordDealDelegate = self; // 获取录音回调
    self.cacheDbSleepArray = nil;
    if ([self.blescanDelegate respondsToSelector:@selector(srBleDidConnectPeripheral:)]) {
        [self.blescanDelegate srBleDidConnectPeripheral:service];
    }
}


- (void) stkeyFobServiceDidDisconnectPeripheral:(SRBLeService*)service {
//    service.recordDealDelegate = nil;
    self.cacheDbSleepArray = nil;
    service.hasBeenAuth = NO;
    if ([self.blescanDelegate respondsToSelector:@selector(srBleDidDisconnectPeripheral:)]) {
        [self.blescanDelegate srBleDidDisconnectPeripheral:service];
    }
    
}
- (void) stkeyFobServiceDidReadRSSI:(SRBLeService*)service {
    
}
- (void) stkeyFobServiceDidReset {
    
}

- (void)stkeyFobServiceBatteryReady {
    // 电池服务完成
}


- (void)stkeyFobServiceDidReadyForReadWrite:(SRBLeService *)service {
    // 同步时间
    [[[SRBleDiscovery sharedInstance] currentService] cmdTimeSync];
    
    // 读写服务准备完成
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleDeviceDidReadyForReadAndWrite:)]) {
        [self.bleDataDelegate srBleDeviceDidReadyForReadAndWrite:service];
    }
    
    
}

// 回调设备信息
- (void)stkeyFobServiceDeviceInfo:(SRDeviceInfo *)devInfo
{
    self.currentDevice.needOemAuth = @(devInfo.needOemAuth); // 标记是否需要厂家认证
    DebugNSLog(@"OEM认证开关 %d", devInfo.needOemAuth);
    self.currentDevice.isSupportSportMode = devInfo.supportSportmode;
    self.currentDevice.chargeType = @(devInfo.chargeType);
    self.currentDevice.isSupportEcg = devInfo.supportECG;
    self.currentDevice.projectId = devInfo.projectId;
    [self functionGetDeviceSN]; //下发获取sn
    
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleDeviceInfo:)]) {
        [self.bleDataDelegate srBleDeviceInfo:devInfo];
    }
    
}

/// 实时计步
/// @param steps 计步
- (void)stkeyFobServiceRealtimeSteps:(NSNumber *)steps {
    return;
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBleDeviceRealtimeSteps:)]) {
//        [self.bleDataDelegate srBleDeviceRealtimeSteps:steps];
//    }
    
}


/// 实时体温
/// @param temperature 体温
- (void)stkeyFobServiceRealtimeTemperaure:(NSNumber *)temperature {
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleDeviceRealtimeTemperature:)]) {
        [self.bleDataDelegate srBleDeviceRealtimeTemperature:temperature];
    }
}

/// 电量回调
/// @param batteryLevel 电量
/// @param isCharging 是否充电
- (void) stkeyFobServiceBatteryLevel:(NSUInteger)batteryLevel IsCharging:(BOOL)isCharging {
    // srBleDeviceBatteryLevel
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleDeviceBatteryLevel:IsCharging:)]) {
        [self.bleDataDelegate srBleDeviceBatteryLevel:batteryLevel IsCharging:isCharging];
    }
    
}


- (void)stkeyFobServiceRealtimeHRV:(NSNumber *)hrv BloodOxygen:(NSNumber *)bloodOxygen HeartRate:(NSNumber *)hr Status:(REALTIME_STATUS)status {
    
    if (status == REALTIME_STATUS_DATA_USEFUL) { // 数据有效
        
        if (hr && [self.bleDataDelegate respondsToSelector:@selector(srBleRealtimeHeartRate:)]) {
            if (hr.intValue >= self.heartrateFilterLowerLimit && hr.intValue <= 180) {
                [self.bleDataDelegate srBleRealtimeHeartRate:hr];
            }
        }
        
        if (bloodOxygen && [self.bleDataDelegate respondsToSelector:@selector(srBleRealtimeSpo:)]) {
            if (bloodOxygen.intValue > 80) {
                if (bloodOxygen.intValue > 100) {
                    bloodOxygen = @(100);
                }
                [self.bleDataDelegate srBleRealtimeSpo:bloodOxygen];
            }
        }
        // srBleRealtimeHrv
        if (hrv && [self.bleDataDelegate respondsToSelector:@selector(srBleRealtimeHrv:)]) {
            [self.bleDataDelegate srBleRealtimeHrv:hrv];
        }
        
    }
    
}

-(void)stkeyFobServiceSN:(NSString *)sn OriginSNData:(NSData *)sndata
{
    // sn 回调
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleSN:) ]) {
        [self.bleDataDelegate srBleSN:sn];
    }
    
    // 开始OEM认证
    self.currentDevice.authSnData = sndata;
    self.currentDevice.snString = sn;
    
    // 是否已认证过,重复获取sn而已
    if (!self.currentDevice.hasBeenAuth && self.currentDevice.needOemAuth.boolValue) {
        [[[SRBleDiscovery sharedInstance] currentService] cmdStartOemAuth];
    }
    
}

-(void)stkeyFobServiceSampleRate:(uint8_t)smpRate WaveSwitch:(BOOL)isOn
{
    // 123
    self.currentDevice.sampleRate = smpRate;
    self.currentDevice.isWaveDataOn = isOn;
}

//// 历史数据
//- (void) stkeyFobServiceHistoryData:(SRHistoryData *)hisData IsComplete:(BOOL)isComplete {
//    // sn 回调
//
//}

-(void)stkeyFobServiceHistorySR03Data:(SRHistoryDataSR03 *)sr03HisData IsComplete:(BOOL)isComplete
{
    
    self.currHisidx++;
//    DebugNSLog(@"收到历史条目: %lu", self.currHisidx);
    if (!self.historyCacheArray) {
        self.historyCacheArray = [NSMutableArray new];
    }
    
    [self.historyCacheArray addObject:sr03HisData];
    
    if (self.historyCacheArray.count == self.historyCacheCount && self.historyCacheCount > 0) {
        isComplete = YES;
    }
    
    if (!isComplete) {
//        if (self.historySyncCbk) {
//            self.historySyncCbk(isComplete, self.historyCacheCount, self.historyCacheArray.count);
//        }
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistorySr03DataWithCurrentCount:IsComplete:) ]) {
//            [self.bleDataDelegate srBleHistorySr03DataWithCurrentCount:self.historyCacheArray.count IsComplete:isComplete];
//        }
        
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
            [self.bleDataDelegate srBleHistoryDataProgress:(self.currHisidx + self.fakeHisIncrease) *1.0f / (self.historyCacheArray.count + self.currHisidx)
                                                IsComplete:isComplete];
        }
        
    }
  
    
    if (isComplete) { // 特殊处理
//        self.lastSyncTimeInteval = @([[NSDate date] timeIntervalSince1970]); //记录同步成功时间
        [self.historyCacheArray sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
            SRHistoryDataSR03 *his1 = obj1;
            SRHistoryDataSR03 *his2 = obj2;
            return [his1.timeStamp compare:his2.timeStamp];
            
        }];
        SDK_WEAK_SELF
        [DBHistoryDataSr03 mutiInsert:self.currentMac
                                Array:self.historyCacheArray
                             Cpmplete:^(NSMutableArray<SRHistoryDataSR03 *> * _Nonnull dataArray, BOOL isSucc)
         {
            SDK_STRONG_SELF
            // 存储到数据库
            
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                // 延迟为了等待保存完毕,狗逼项目,管你大爷的.
                SDK_STRONG_SELF
//                if ([strongSelf.bleDataDelegate respondsToSelector:@selector(srBleHistorySr03DataWithCurrentCount:IsComplete:)]) {
//                    [strongSelf.bleDataDelegate srBleHistorySr03DataWithCurrentCount:self.historyCacheArray.count IsComplete:isComplete]; // 进度条回调
//                }
                if ([strongSelf.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
                    [strongSelf.bleDataDelegate srBleHistoryDataProgress:(strongSelf.currHisidx + strongSelf.fakeHisIncrease) *1.0f / (strongSelf.historyCacheArray.count + strongSelf.currHisidx)
                                                        IsComplete:isComplete];
                }
                
                [strongSelf calcThisSyncDataSleep:^(NSDate *everyFinishDate) { // 计算此次同步数据的睡眠
                    SDK_STRONG_SELF
                    DebugNSLog(@"lzp calcThisSyncDataSleep 回调 %@", everyFinishDate);
//                    self.cahceDbSleepArray = nil;
                  
                    if (strongSelf.historyCacheCount >= 12*24*4) {
                        // 清空设备历史数据
                        [strongSelf functionClearDeviceHistoryCache];
                    }
                    
                    strongSelf.historyCacheCount = 0;
                    strongSelf.fakeHisIncrease = 0;
                    strongSelf.historyCacheArray = nil;
                    
                    NSDate *todayBegin = [TimeUtils zeroOfDate:[NSDate date]];
                    if ([strongSelf.bleDataDelegate respondsToSelector:@selector(calculatSleepFinish)]) {
                        [strongSelf.bleDataDelegate calculatSleepFinish];
                    }

                    strongSelf.cacheDbSleepArray = nil;

                }];
                
            });
            
            
           
        }];
        
        // debu使用
        if (self.debugCollect) {
            [DebugDBHistoryDataALL mutiInsertAlldata:self.currentMac Array:self.historyCacheArray Cpmplete:^(NSMutableArray<SRHistoryDataSR03 *> * _Nonnull dataArray, BOOL isSucc) {
                
            }];
        }
      
    }
    
    
    // srBleHistorySr03Data
    
}


/// 执行命令情况
/// @param cmd 下发的命令
/// @param isSuccess YES = 执行成功
- (void) stkeyFobServiceSendCmdExcute:(uint8_t)cmd Succ:(BOOL)isSuccess Reason:(CMD_EXECTE_ERROR_REASON)reason {
    
    if (cmd == EXCUTED_CMD_HIS_DATA && !isSuccess ) {
        self.historyCacheCount = 0;
        self.fakeHisIncrease = 0;
        [self.historyCacheArray removeAllObjects];
//        if (self.historySyncCbk) {
//            self.historySyncCbk(YES, 1, 1); // 回调进度条完成
//        }
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistorySr03DataWithCurrentCount:IsComplete:) ]) {
//            [self.bleDataDelegate srBleHistorySr03DataWithCurrentCount:0 IsComplete:YES];
//        }
        
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
//            [self.bleDataDelegate srBleHistoryDataProgress:1
//                                                IsComplete:YES];
//        }
        
    }
    
//    if (cmd == EXCUTED_CMD_HIS_DATA && !isSuccess && reason == REASON_1) {
//        // 自动测量中 延时下发获取数据
//        if (self.fakeHisIncrease <= (NSInteger)(self.historyCacheCount * 0.5)) {
//            __weak typeof(self) weakSelf = self;
//            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//                
//                [weakSelf functionGetHistoryDataOnlyData]; //再次获取数据
//            });
//            self.fakeHisIncrease += (NSInteger)(self.historyCacheCount * 0.05);
//            
////            self.historySyncCbk(NO, self.fakeHisIncrease + self.historyCacheCount, self.fakeHisIncrease);
//            
//            if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
//                [self.bleDataDelegate srBleHistoryDataProgress:(self.currHisidx + self.fakeHisIncrease) *1.0f / (self.historyCacheArray.count + self.currHisidx)
//                                                    IsComplete:NO];
//            }
//            
//            
//        } else {
//            self.historyCacheCount = 0;
//            self.fakeHisIncrease = 0;
//            [self.historyCacheArray removeAllObjects];
////            if (self.historySyncCbk) {
////                self.historySyncCbk(YES, 1, 1); // 回调进度条完成
////            }
//            if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
//                [self.bleDataDelegate srBleHistoryDataProgress:1
//                                                    IsComplete:YES];
//            }
//        }
//        
//    }
    
    
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleCmdExcute:Succ:Reason:) ]) {
        [self.bleDataDelegate srBleCmdExcute:cmd Succ:isSuccess Reason:reason];
    }
}

- (void) stkeyFobService:(BOOL)isSosOpen
          DoubleTapTimes:(uint8_t)doubleTapTimes
       SingleTapInterval:(uint8_t)singleTapInterval TapDetectionThreshold:(uint8_t)tapDetectionThreshold
DoubleTapEffectStartTime:(uint8_t)doubleTapEffectStartTime DoubleTapEffectEndTime:(uint8_t)doubleTapEffectEndTime Isbinded:(BOOL)isBinded
{
    self.currentDevice.isBinded = isBinded;
    DebugNSLog(@"回调绑定状态 %d", isBinded);
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleIsbinded:) ])
    {
        [self.bleDataDelegate srBleIsbinded:isBinded];
    }
    /*!self.currentDevice.hasBeenAuth && self.currentDevice.needOemAuth*/
    if (self.currentDevice.needOemAuth
        && !self.currentDevice.needOemAuth.boolValue
        && !self.currentDevice.hasBeenAuth)
    {
        // 无需认证 && 还没走完认证流程
        [self stkeyFobServiceAESAuthResult:YES];
    }
}

- (void) stkeyFobServiceSOShappen {
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBleSOShappen) ]) {
//        [self.bleDataDelegate srBleSOShappen];
//    }
    
}

// sos时的测量数据
- (void)stkeyFobServiceSOSData:(float)temperature HeartRate:(NSInteger)hr BloodOxygen:(NSInteger)bloodOxygen
{
    
//    if ([self.bleDataDelegate respondsToSelector:@selector(srBlesSOSData:HeartRate:BloodOxygen:)]) {
//        [self.bleDataDelegate srBlesSOSData:temperature HeartRate:hr BloodOxygen:bloodOxygen];
//    }
    
}

- (void) stkeyFobServiceHistoryTimeout {
    
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataTimeout) ]) {
        [self.bleDataDelegate srBleHistoryDataTimeout];
    }
}

- (void) stkeyFobServiceHistoryCount:(NSInteger)count {
    
  
    
    self.historyCacheCount = count;
    self.currHisidx = 0;
    self.fakeHisIncrease = 0;
    if (self.historyCacheCount == 0) {
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataCount:) ]) {
//            [self.bleDataDelegate srBleHistoryDataCount:1];
//        }
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistorySr03DataWithCurrentCount:IsComplete:) ]) {
//            [self.bleDataDelegate srBleHistorySr03DataWithCurrentCount:1 IsComplete:YES];
//        }
        
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataProgress:IsComplete:)]) {
            [self.bleDataDelegate srBleHistoryDataProgress:1 IsComplete:YES];
        }
        
        // 计算一次睡眠
        SDK_WEAK_SELF
        [self calcThisSyncDataSleep:^(NSDate *everyFinishDate) {
            SDK_STRONG_SELF
            
            if ([strongSelf.bleDataDelegate respondsToSelector:@selector(calculatSleepFinish)]) {
                [strongSelf.bleDataDelegate calculatSleepFinish];
            }
            strongSelf.cacheDbSleepArray = nil;

        }];
       
    } else {
//        if ([self.bleDataDelegate respondsToSelector:@selector(srBleHistoryDataCount:) ]) {
//            [self.bleDataDelegate srBleHistoryDataCount:count];
//        }
        // 开始获取历史数据
        [[[SRBleDiscovery sharedInstance] currentService] cmdHistoryData];
    }
    
}

-(void)stkeyFobServiceEcg:(SrEcgData *)ecgObj
{
    DebugNSLog(@"ecg callback stkeyFobServiceEcg");

    if (self.isRowWave.boolValue) {
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleEcgWave:)]) {
            [self.bleDataDelegate srBleEcgWave:ecgObj];
        }
    }
    if (self.isRowWave && !self.isRowWave.boolValue) {
        // 神念
        for (NSNumber * ecg in ecgObj.ecgArray) {
            [self.algoEcgSdkObj requestECGAnalysis:ecg.intValue withPoorSignal:200];

        }

    }
    
    
}

-(void)stkeyFobServiceEcgAndPPg:(SrEcgData *)ecgPpgObj
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleEcgAndPPgWave:)]) {
        [self.bleDataDelegate srBleEcgAndPPgWave:ecgPpgObj];
    }

    
}

- (void)stkeyFobServiceEcgResult:(SrEcgAlgorithmResults *)ecgResult
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleEcgAlgorithmResult:)]) {
        [self.bleDataDelegate srBleEcgAlgorithmResult:ecgResult];
    }
}
- (void)stkeyFobServiceEcgLeadOn:(BOOL)leadOn
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleEcgEcgLeadOn:)]) {
        [self.bleDataDelegate srBleEcgEcgLeadOn:leadOn];
    }
}

#pragma mark --AES
- (void)stkeyFobServiceAESRecvR1:(NSData *)r1
{
    // 解密出原文r2
    NSData *r2 = [SDKTool oemAesDecreat:self.currentDevice.authSnData Company:self.aesCompany R1:r1];
    //
    [self.currentDevice cmdOEMSendR2:r2];
}

/// 设备上报认证最后结果
/// - Parameter isAuthed: YES = auth pass
- (void)stkeyFobServiceAESAuthResult:(BOOL)isAuthed
{
    self.currentDevice.hasBeenAuth = YES;
    
    // 同步时间
    [[[SRBleDiscovery sharedInstance] currentService] cmdTimeSync];
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleOEMAuthResult:)])
    {
        [self.bleDataDelegate srBleOEMAuthResult:isAuthed];
    }
    
}


/// 设备信息5
/// - Parameters:
///   - durations: 心率 体温测量时长
///   - pd_threshold: pd阈值
///   - pd_range_1:pd波动 范围1
///   - pd_range_2: pd采样波动 范围2
-(void)stkeyFobServiceHrMeasuDuration:(NSInteger)durations PD_THRESHOLD:(uint32_t)pd_threshold PD_RANGE_1:(uint32_t)pd_range_1 PD_RANGE_2:(uint32_t)pd_range_2
{
    
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleMeasureDuration:)]) {
        [self.bleDataDelegate srBleMeasureDuration:durations];
    }
    
    
}

- (void)stkeyFobServiceOxygenMeasureInterval:(uint16_t)minuteInterval OxygenSwitch:(BOOL)on
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleOxygenMeasureInterval: OxygenSwitch:)]) {
        [self.bleDataDelegate srBleOxygenMeasureInterval:minuteInterval OxygenSwitch:on];
    }
    
}

// 血氧红外
- (void)stkeyFobServiceIrData:(uint16_t)irData
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleIrData:)]) {
        [self.bleDataDelegate srBleIrData:irData];
    }
    
}
// 红光
- (void)stkeyFobServiceRedData:(uint16_t)redData
{
    if ([self.bleDataDelegate respondsToSelector:@selector(srBleRedData:)]) {
        [self.bleDataDelegate srBleRedData:redData];
    }
}



#pragma mark - OTA
-(void)functionStartOta:(NSURL *)fileUrl {
    self.otaManager = [[SROtaManager alloc]initWithService:
                       [[SRBleDiscovery sharedInstance] currentService] ];
    self.otaManager.bleOtaDelegate = self.bleOtaDelegate;
    [self.otaManager startOta:fileUrl];
    
    
}

#pragma mark -- 从deviceCenter抄的
// 保存体温
//-(void)saveThermemoterCacheData:(NSMutableArray<SRHistoryDataSR03 *> *)dataArray
//{
//    NSMutableArray<SRHistoryDataSR03 *> * tempArray = dataArray;
//
//    SDK_WEAK_SELF
//    [DBThermemoter queryMaxTime:self.currentMac
//                     Cpmplete:^(NSNumber * _Nullable maxTimeStamp)
//     {
//        SDK_STRONG_SELF
//        NSTimeInterval maxTime = maxTimeStamp.doubleValue;
//        [tempArray enumerateObjectsUsingBlock:^(SRHistoryDataSR03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//
//            BOOL canSave = YES;//obj.skinTemp.floatValue >= 35.2; //下限
//            if (obj.timeStamp.doubleValue > maxTime && obj.skinTemp != nil && canSave) {
//                // 大于此时间才保存
//                DBThermemoter *therObj = [[DBThermemoter alloc]initWith:[NSDate dateWithTimeIntervalSince1970:obj.timeStamp.doubleValue] Value:obj.skinTemp Account:self.currentMac];
//                [therObj insert:nil];
//            }
//
//        }];
//
//        DebugNSLog(@"保存体温完毕");
//    }];
//}

// 保存血氧
//-(void)saveOxygenCacheData:(NSMutableArray<SRHistoryDataSR03 *> *)dataArray
//{
//    NSMutableArray<SRHistoryDataSR03 *> * tempArray = dataArray;
//
//    SDK_WEAK_SELF
//    [DBOxygen queryMaxTime:self.currentMac
//                     Cpmplete:^(NSNumber * _Nullable maxTimeStamp)
//     {
//        SDK_STRONG_SELF
//        NSTimeInterval maxTime = maxTimeStamp.doubleValue;
//        [tempArray enumerateObjectsUsingBlock:^(SRHistoryDataSR03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//            if (obj.timeStamp.doubleValue > maxTime && obj.bloodOxygen != nil) {
//                // 大于此时间才保存
//                DBOxygen *oxygenObj = [[DBOxygen alloc]initWith:[NSDate dateWithTimeIntervalSince1970:obj.timeStamp.doubleValue] Value:obj.bloodOxygen Account:self.currentMac];
//                [oxygenObj insert:nil];
//            }
//
//        }];
//
//        DebugNSLog(@"保存血氧完毕");
//    }];
//}
// 保存计步
//-(void)saveStepsCacheData:(NSMutableArray<SRHistoryDataSR03 *> *)dataArray
//{
//    NSMutableArray<SRHistoryDataSR03 *> * tempArray = dataArray;
//
//    SDK_WEAK_SELF
//    [DBSteps queryMaxTime:self.currentMac
//                     Cpmplete:^(NSNumber * _Nullable maxTimeStamp)
//     {
//        SDK_STRONG_SELF
//        NSTimeInterval maxTime = maxTimeStamp.doubleValue;
//        [tempArray enumerateObjectsUsingBlock:^(SRHistoryDataSR03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//            if (obj.timeStamp.doubleValue > maxTime && obj.steps != nil) {
//                // 大于此时间才保存
//                DBSteps *stepObj = [[DBSteps alloc]initWith:[NSDate dateWithTimeIntervalSince1970:obj.timeStamp.doubleValue]
//                                                      Value:obj.steps
//                                                    Account:self.currentMac];
//                if (stepObj.value) {
////                    DebugNSLog(@"插入计步 :%@", stepObj.value);
//                    // 先计算卡路里
////                    [stepObj calcCalorie:[AccountCenter instance].currentAccount.otherInfo.height.floatValue
////                                  Weight:[AccountCenter instance].currentAccount.otherInfo.weight.floatValue];
//                    [stepObj insert:nil];
//                }
//
//            }
//
//        }];
//
//        DebugNSLog(@"保存计步完毕");
//    }];
//}

// 保存心率
//-(void)saveHeartCacheData:(NSMutableArray<SRHistoryDataSR03 *> *)dataArray
//{
//    NSMutableArray<SRHistoryDataSR03 *> * tempArray = dataArray;
//    SDK_WEAK_SELF
//    [DBHeartRate queryMaxTime:self.currentMac
//                     Cpmplete:^(NSNumber * _Nullable maxTimeStamp)
//     {
//        SDK_STRONG_SELF
//        NSTimeInterval maxTime = maxTimeStamp.doubleValue;
//        [tempArray enumerateObjectsUsingBlock:^(SRHistoryDataSR03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//            BOOL canSave = obj.deviceModifyHeartRate.floatValue >= 50.f && obj.deviceModifyHeartRate.floatValue <= 175.f;  // 心率取值范围
//
//            if (obj.timeStamp.doubleValue > maxTime && obj.deviceModifyHeartRate.intValue > 30 && canSave) {
//                // 大于此时间才保存
//                DBHeartRate *heartRateObj = [[DBHeartRate alloc]initWith:[NSDate dateWithTimeIntervalSince1970:obj.timeStamp.doubleValue] Value:obj.deviceModifyHeartRate Account:self.currentMac];
//                [heartRateObj sleepHeartRateFix:obj.soprtTimes.floatValue]; //修正睡眠期间数据
//                [heartRateObj insert:nil];
//            }
//
//        }];
//        DebugNSLog(@"保存心率完毕");
//    }];
//}

// 保存hrv
//-(void)saveHrvCacheData:(NSMutableArray<SRHistoryDataSR03 *> *)dataArray
//{
//    NSMutableArray<SRHistoryDataSR03 *> * tempArray = dataArray;
//
//    SDK_WEAK_SELF
//    [DBHrv queryMaxTime:self.currentMac
//                     Cpmplete:^(NSNumber * _Nullable maxTimeStamp)
//     {
//        SDK_STRONG_SELF
//        NSTimeInterval maxTime = maxTimeStamp.doubleValue;
//        [tempArray enumerateObjectsUsingBlock:^(SRHistoryDataSR03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//            NSNumber *hrv = [obj calcHRv]; // hrv为本地计算
//            if (obj.timeStamp.doubleValue > maxTime && hrv.intValue > 0) {
//                // 大于此时间才保存
//                DBHrv *hrvObj = [[DBHrv alloc]initWith:[NSDate dateWithTimeIntervalSince1970:obj.timeStamp.doubleValue] Value:hrv Account:self.currentMac];
//                [hrvObj insert:nil];
//            }
//
//        }];
//
//        DebugNSLog(@"保存hrv完毕");
//    }];
//}


//-(void)calcSleep:(NSDate *)date Account:(NSString *)account Complete:(void(^)(SleepStagingResultV2 *sleepResult, NSNumber * restHr, NSDate * restHrBeginDate, NSDate * restHrEndDate))cpmplete
//{
//    NSDate * calcSleepDate = date;
//
//
//    // 1 取数据
//
//    // 测试
//    SDK_WEAK_SELF
//
//    // 实际业务
//    NSTimeInterval spanSecs = 8 * 60 * 60; // 跨度 单位 秒
//    NSDate *beforeZeroDate = [TimeUtils zeroOfBeforeDayDate:calcSleepDate];
//
//    NSDate *beginDate = [beforeZeroDate dateByAddingTimeInterval:spanSecs]; // 从前一天的八点到今天晚上23:59
//    NSDate *nextDayZero = [TimeUtils zeroOfNextDayDate:calcSleepDate];
//
//    [DBHistoryDataSr03 queryForSleepCalcBy:account
//                                     Begin:beginDate
//                                       End:nextDayZero
//                           OrderBeTimeDesc:NO
//                                  Cpmplete:^(NSMutableArray<NSMutableDictionary *> * _Nonnull results, NSNumber * _Nonnull restHr)
//     {
//        SDK_STRONG_SELF
//        // 2 计算睡眠
//        SleepStagingResultV2 *sleepResult = [strongSelf.sleepStageCalcObj findSleepData:results];
//        if (cpmplete) {
//            cpmplete(sleepResult, restHr, beginDate, nextDayZero);
//        }
//    }];
//
//
//}

#pragma mark -- ECG 神念
// 神念滤波回调
- (void)dataReceived:(ECGAlgorithmsData)algo results:(int)value {
    if (algo == ECG_SMOOTHED_WAVE) {
      
            //            [ecgLineView addValue:value];
//        if ([self.sdkHealthMoniterdelegate respondsToSelector:@selector(receiveECGDataSmoothedWave:)]) {
//            [self.sdkHealthMoniterdelegate receiveECGDataSmoothedWave:value];
//        }
        // -(void)srBleEcgWave:(SrEcgData *)ecgObj;
        if ([self.bleDataDelegate respondsToSelector:@selector(srBleEcgWave:)]) {
            SrEcgData *data = [[SrEcgData alloc]init];
            data.type = SRECG_TYPE_ONLY_ECG;
            data.ecgArray = [NSMutableArray new];
            [data.ecgArray addObject:@(value)];
            [self.bleDataDelegate srBleEcgWave:data];
        }
        DebugNSLog(@"ecg wave 神念:%d", value);
    }
}


// 计算呼吸率
-(NSNumber *)calcBreathRateDuraingSleep:(StagingDataV2 *)sleepStageData
{
    if (sleepStageData != nil) {
        return @(sleepStageData.averageHr / 4);
    }
    
    return nil;
    
}



// 外部查询睡眠
-(void)sdkQuerySleepFrom:(NSDate *)beginDate To:(NSDate *)endDate DeviceMacaddrss:(NSString *)masAddress Complete:(void(^)(void))cpmplete
{
    
}

#pragma mark --睡眠相关
// 将此次同步的数据全部计算睡眠
-(void)calcThisSyncDataSleep:(void(^)(NSDate * everyFinishDate))everyCmpBlk {

    
    if (self.cacheDbSleepArray != nil) {
        return;
    }
    
    self.cacheDbSleepArray = [NSMutableArray new];
//    NSString *account = [AccountCenter instance].currentAccount.account;
    SDK_WEAK_SELF
    [DBSleepData queryFirstAndLastTimeOnlyForSleepCalc:self.currentMac Cmp:^(NSNumber * _Nonnull lastEndtime,  NSNumber * firsttime,  NSNumber *firstDataTime) {
        SDK_STRONG_SELF
        // lastEndtime 最后一个睡眠缓存结束时间
        NSDate *beginDate = [NSDate dateWithTimeIntervalSince1970:lastEndtime.doubleValue];
        NSDate *endDate = [NSDate date];
        
        if (lastEndtime.intValue > 0) {
            beginDate = [NSDate dateWithTimeIntervalSince1970:lastEndtime.doubleValue];
        } else {
            // 没有睡眠缓存
            if (firstDataTime != nil) {
                beginDate = [NSDate dateWithTimeIntervalSince1970:firstDataTime.doubleValue];
                DebugNSLog(@"首个历史数据时间 %@", firstDataTime);
            } else {
                if (everyCmpBlk) {
                    everyCmpBlk(beginDate);
                }
                return; // 没有数据无需计算
//                beginDate = [endDate dateBySubtractingDays:90]; //倒退80天
            }
        }
        DebugNSLog(@"lzp 开始批量算睡眠");
//        beginDate = [TimeUtils zeroOfDate:beginDate];
//        NSUInteger days = [beginDate daysEarlierThan:endDate]; // 相差几天
        
//        while (![beginDate isLaterThanOrEqualTo:endDate]) {
            [strongSelf calcSleepByDate:beginDate EndDate:endDate Complete:^(SleepStagingResultV2 *sleepResult) {
                
//                BOOL shouldEnd = [[beginDate dateByAddingDays:1] isLaterThanOrEqualTo:endDate];
                if (sleepResult.stagingDataList.count > 0) {

                    [sleepResult.stagingDataList enumerateObjectsUsingBlock:^(StagingDataV2 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                        DBSleepData *dbSlepData = [DBSleepData dbDataWithmacAddress:self.currentMac StagingData:obj];
                        if (dbSlepData) {
//                            DebugNSLog(@"lzp 历史睡眠计算 %@ to %@", [NSDate dateWithTimeIntervalSince1970:obj.startTime], [NSDate dateWithTimeIntervalSince1970:obj.endTime] );
                            
                            [strongSelf.cacheDbSleepArray addObject:dbSlepData];
                            
                        }
                    
                    }];
                    [strongSelf.cacheDbSleepArray  enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                        DBSleepData *dbSlepData = (DBSleepData * )obj;
                        [dbSlepData doOtherCalcAndSaveComplete:^(BOOL succ) {
//                            DebugNSLog(@"lzp 批量睡眠存储回调 %d", succ);
                            if (dbSlepData == strongSelf.cacheDbSleepArray.lastObject
                                && everyCmpBlk) {
                                everyCmpBlk([NSDate dateWithTimeIntervalSince1970:dbSlepData.sleepEnd.doubleValue]);
                            }
                        }];
                    }];
                    
                   
                  
                    
                } else {
                    // 没有睡眠
                    if (strongSelf.cacheDbSleepArray.count == 0 && everyCmpBlk) {
                        everyCmpBlk(nil);
                    }
                }
                
            }];
            
//            beginDate = [beginDate dateByAddingDays:1];
        

    }];

}

-(void)calcSleepByDate:(NSDate *)beginDate EndDate:(NSDate *)endDate Complete:(void(^)(SleepStagingResultV2 *sleepResult))cmpBlk {

    
    SDK_WEAK_SELF
    
    [DBHistoryDataSr03 queryForSleepCalcBy:self.currentMac
                                     Begin:beginDate
                                       End:endDate
                           OrderBeTimeDesc:NO
                            NeedCalcRestHr:YES
                                  Cpmplete:^(NSMutableArray<NSMutableDictionary *> * _Nonnull results, NSMutableArray<DBHistoryDataSr03 *> *objArray)
     {
        SDK_STRONG_SELF
      
        
//        [TestUtils saveOriginDataForSleepCalc:results];
        
        
        SleepStagingV2 *calcObj = [[SleepStagingV2 alloc]init];// 睡眠计算对象
        
        // 2 计算睡眠 V2
//        SleepStagingResultV2 *sleepResult = [calcObj findSleepData:results];
        
        /* v3 */
        NSMutableArray<SleepSourceData *> *sourceDatas = [NSMutableArray new];
        [objArray enumerateObjectsUsingBlock:^(DBHistoryDataSr03 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            SleepSourceData *sd = [[SleepSourceData alloc]init];
            sd.time = obj.time;    //时间戳
            sd.soprtTimes = obj.soprtTimes;// 运动计数
            sd.deviceModifyHeartRate  = obj.deviceModifyHeartRate ; // 心率
            sd.hrv = obj.hrv;    // hrv
            sd.steps  = obj.steps; // 计步
            [sourceDatas addObject:sd];
        }];
        
        SleepStagingResultV2 *sleepResult = [calcObj findSleepDataByLib:sourceDatas];
        
        
        /* v3 */
        [sleepResult.stagingDataList enumerateObjectsUsingBlock:^(StagingDataV2 * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
            DebugNSLog(@"sleep 计算 idx=%lu 睡眠开始 %@ 睡眠结束 %@", (unsigned long)idx,
                       [calcObj TestformatTimeStamp:obj.startTime],
                       [calcObj TestformatTimeStamp:obj.endTime]);

        }];
        
//        if (sleepResult.stagingDataList.count > 1) {
//            DebugNSLog(@"发现2段睡眠 %@", [nextDayZero dateBySubtractingHours:1]);
//        }
        if (cmpBlk) {
            cmpBlk(sleepResult);
        }
        
    }];
}


// 发命令前的保护
-(FUNCTION_ERROR)functionProtect:(BOOL)needAuth {
    FUNCTION_ERROR error = FUNCTION_ERR_NONE;
    // 未连接
    if ([[SRBleDiscovery sharedInstance] currentService].peripheral.state != CBPeripheralStateConnected) {
        error = FUNCTION_ERR_BLE_NOT_CONNECT;
        return error;
    }
    
    // 读写未准备好
    if (! [[[SRBleDiscovery sharedInstance] currentService] characteristicReadWriteReady]) {
        error = FUNCTION_ERR_BLE_NOTREADY_READWRITE;
        return error;
    }
    
    // oem认证未结束
    if (needAuth && !self.currentDevice.hasBeenAuth) {
        error = FUNCTION_ERR_OEMAUTH_NOTFINISH;
        return error;
    }
    
    return error;
}

-(void)createDbTables {
    
#if DEBUG
//    [DBHistoryDataSr03 dropTable];
#endif
    
    [DBDevices createTable];   // 账户设备
    [DBHistoryDataSr03 createTable]; // 历史总表

    [DBSleepData createTable]; //睡眠记录
    [DebugDBHistoryDataALL createTable];// debug 日本用 2025-1-8
      
}

-(NSString *)currentMac
{
    return self.currentPerphelServc.macAddress;
}

-(NSKAlgoSDKECG *)algoEcgSdkObj
{
    if (!_algoEcgSdkObj) {
        NSString * licenseKey = @"4DYD5nkbZHYoJBqIxT3nc/QIB58doR7BiRxuH62Ayhs=";
        int sampleRate = 512;
        _algoEcgSdkObj = [[NSKAlgoSDKECG alloc]init];
        [_algoEcgSdkObj setDelegate:self];
        [_algoEcgSdkObj setupSDKProperty:licenseKey withSampleRate:sampleRate enableSmoothed:1];
        [_algoEcgSdkObj enableNSLogMessages:false];
    }
    return _algoEcgSdkObj;
}

@end
